/// @tags: SegmentTree Split
#include <cstdio>
#include <iostream>
#include <stack>
#define rint register int

using std::cin;
using std::cout;

namespace BlueQuantum {

typedef long long LL;

constexpr int maxn = 2e5 + 3, segn = maxn * 20;

int n, m, segcnt, scnt = 1;
int rt[maxn], ls[segn], rs[segn];
LL sum[segn];
std::stack<int> stk;

inline int allocate() {
  if (stk.empty()) return ++segcnt;
  int res = stk.top();
  stk.pop();
  return res;
}

inline void del(int &p) {
  stk.push(p);
  ls[p] = rs[p] = sum[p] = 0;
  p = 0;
}

void modify(int &u, int l, int r, int pos, int v) {
  if (!u) u = allocate();
  sum[u] += v;
  if (l == r) return;
  int mid = (l + r) >> 1;
  pos <= mid ? modify(ls[u], l, mid, pos, v) : modify(rs[u], mid + 1, r, pos, v);
}

LL query(int u, int l, int r, int xl, int xr) {
  if (xr < l || r < xl) return 0;
  if (xl <= l && r <= xr) return sum[u];
  int mid = (l + r) >> 1;
  return query(ls[u], l, mid, xl, xr) + query(rs[u], mid + 1, r, xl, xr);
}

int getKth(int u, int l, int r, int k) {
  if (l == r) return l;
  int mid = (l + r) >> 1;
  return sum[ls[u]] >= k ? getKth(ls[u], l, mid, k) : getKth(rs[u], mid + 1, r, k - sum[ls[u]]);
}

void merge(int &x, int y) {
  if (!x || !y) {
    x |= y;
    return;
  }
  sum[x] += sum[y];
  merge(ls[x], ls[y]);
  merge(rs[x], rs[y]);
  del(y);
}

void split(int x, int &y, LL k) {
  if (x == 0) return;
  y = allocate();
  LL v = sum[ls[x]];
  if (k > v) {
    split(rs[x], rs[y], k - v);
  } else {
    std::swap(rs[x], rs[y]);
  }
  if (k < v) {
    split(ls[x], ls[y], k);
  }
  sum[y] = sum[x] - k;
  sum[x] = k;
  return;
}

inline int main() {
  int n, m;
  cin >> n >> m;
  for (int i = 1; i <= n; ++i) {
    int x;
    cin >> x;
    modify(rt[1], 1, n, i, x);
  }
  for (int i = 1; i <= m; ++i) {
    int opt, p, x, y;
    cin >> opt >> p >> x;
    switch (opt) {
      case 0: {
        cin >> y;
        LL k1 = query(rt[p], 1, n, 1, y), k2 = query(rt[p], 1, n, x, y);
        int tmp = 0;
        split(rt[p], rt[++scnt], k1 - k2);
        split(rt[scnt], tmp, k2);
        merge(rt[p], tmp);
      } break;
      case 1:
        merge(rt[p], rt[x]);
        break;
      case 2:
        cin >> y;
        modify(rt[p], 1, n, y, x);
        break;
      case 3:
        cin >> y;
        cout << query(rt[p], 1, n, x, y) << '\n';
        break;
      case 4:
        if (sum[rt[p]] < x) {
          cout << "-1\n";
          continue;
        }
        cout << getKth(rt[p], 1, n, x) << '\n';
        break;
    }
  }
  return 0;
}

}  // namespace BlueQuantum

int main() {
#ifndef ONLINE_JUDGE
#ifdef LOCAL
  freopen("/tmp/CodeTmp/testdata.in", "r", stdin);
  freopen("/tmp/CodeTmp/testdata.out", "w", stdout);
#else
  freopen("SegSplit.in", "r", stdin);
  freopen("SegSplit.out", "w", stdout);
#endif
#endif

  std::ios::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
  return BlueQuantum::main();
}
